home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ntp / depredated / ntp.3.4 / patches / patch13.Z / patch13
Encoding:
Text File  |  1991-09-29  |  52.4 KB  |  1,914 lines

  1. System: ntp version 3.4
  2. Patch #: 13
  3. Priority: medium
  4. From: louie@trantor.umd.edu
  5.  
  6. Description:
  7. A few cosmetic changes in ntp.c for the case when udp/ntp is not in the
  8. /etc/services file.
  9.  
  10. A few extra diddles in ntp.h for the reference clock feature.
  11.  
  12. A couple of changes to debug NeXT support in ntp_adjust.c
  13.  
  14. Changes for reference clock feature in ntp_proto.c
  15.  
  16. In ntp_sock.c, change the order that the bind() call is done for each socket.
  17. It turns out that if you have the Multicast code installed, incoming packets
  18. will be delived to the *first* socket that matches.  It also turns out that
  19. when binding sockets, the first one bound is the last on checked, so we want
  20. to bind the wildcard socket first.
  21.  
  22. Changes in ntpd.c for reference clock support.  Also, a few diddles to
  23. accomodate the NeXT computer system that has a slightly different nlist.h
  24.  
  25. A few cosmetic changes for ntpd.c
  26.  
  27. Added support few a new type of unsigned long to double compiler brokenness,
  28. called GENERIC_UNS_BUG.  If this is defined, then the unsigned long is
  29. shifted right one bit, the high-order bit of the result is cleared, then
  30. converted to a double.  The double is multiplied by 2.0, and the a 1.0 is
  31. optionall added to it if the low order bit of the original unsigned long
  32. was set.  Whew!
  33.  
  34. Add test for GENERIC_UNS_BUG to test.c
  35.  
  36. Repeat-By:
  37.  
  38. Fix:    From rn, say "| patch -p -N -d DIR", where DIR is your ntp source
  39.     directory.  Outside of rn, say "cd DIR; patch -p -N <thisarticle".
  40.     If you don't have the patch program, apply the following by hand,
  41.     or get patch (version 2.0, latest patchlevel).
  42.  
  43.     After patching:
  44.         make depend
  45.         make
  46.         make install
  47.  
  48.     If patch indicates that patchlevel is the wrong version, you may need
  49.     to apply one or more previous patches, or the patch may already
  50.     have been applied.  See the patchlevel.h file to find out what has or
  51.     has not been applied.  In any event, don't continue with the patch.
  52.  
  53.     If you are missing previous patches they can be obtained from me:
  54.  
  55.     Louis A. Mamakos
  56.     louie@trantor.umd.edu
  57.  
  58.     You can also get the patches via anonymous FTP from
  59.     trantor.umd.edu.
  60.  
  61. Index: patchlevel.h
  62. Prereq: 12
  63. 1c1
  64. < #define PATCHLEVEL 12
  65. ---
  66. > #define PATCHLEVEL 13
  67.  
  68. Index: Makefile
  69. *** Makefile.old    Thu May 18 18:37:56 1989
  70. --- Makefile    Thu May 18 18:37:59 1989
  71. ***************
  72. *** 1,6 ****
  73. ! # $Source: /usr/users/louie/ntp/RCS/Makefile,v $ $Revision: 3.4.1.6 $ $Date: 89/05/03 15:08:06 $
  74.   #
  75.   # $Log:    Makefile,v $
  76.   # Revision 3.4.1.6  89/05/03  15:08:06  louie
  77.   # In the Makefile, remove references to the readclock.c module.
  78.   # 
  79. --- 1,10 ----
  80. ! # $Source: /usr/users/louie/ntp/RCS/Makefile,v $ $Revision: 3.4.1.7 $ $Date: 89/05/18 12:43:32 $
  81.   #
  82.   # $Log:    Makefile,v $
  83. + # Revision 3.4.1.7  89/05/18  12:43:32  louie
  84. + # Add preliminary support of NeXT machine, new floating point bug work-around
  85. + # and reference clock support.
  86. + # 
  87.   # Revision 3.4.1.6  89/05/03  15:08:06  louie
  88.   # In the Makefile, remove references to the readclock.c module.
  89.   # 
  90. ***************
  91. *** 76,81 ****
  92. --- 80,87 ----
  93.   #    SETTICKADJ - attempt to modify kernel's `tickadj' variable at run time.
  94.   #    REFCLOCK  - define if you have a reference clock attached to your
  95.   #            machine.  (untested by UMD)
  96. + #    PSTI - define along with REFCLOCK if you have a PSTI clock attached
  97. + #        that you'd like to use a a reference clock.
  98.   #    XTAL=0 - for line freq clock, or
  99.   #    XTAL=1      for crystal controlled clock (default)
  100.   #    LOG_NTP=foo - to change the syslog facility.  You could specify
  101. ***************
  102. *** 84,91 ****
  103.   #    NOSWAP - allow use of plock() to prevent swapping
  104.   #
  105.   
  106. ! # FEATURES=
  107. ! FEATURES= -DBROADCAST_NTP -DSETTICKADJ -DDEBUG
  108.   
  109.   # for 4.3 BSD
  110.   DEFINES=
  111. --- 90,98 ----
  112.   #    NOSWAP - allow use of plock() to prevent swapping
  113.   #
  114.   
  115. ! #FEATURES= -DBROADCAST_NTP -DSETTICKADJ -DDEBUG
  116. ! #FEATURES= -DSETTICKADJ -DDEBUG -DREFCLOCK -DPSTI
  117. ! FEATURES= -DSETTICKADJ -DDEBUG -DREFCLOCK
  118.   
  119.   # for 4.3 BSD
  120.   DEFINES=
  121. ***************
  122. *** 93,105 ****
  123.   # for Sun
  124.   #DEFINES= -DSUN_FLT_BUG
  125.   
  126. ! # for Ultrix 2.0/2.2/3.0
  127.   # don't forget to fix the broken definition of inet_addr in netdb.h
  128.   # it should be declared as a u_long not a in_addr  (the doc is wrong also)
  129. ! # (Note 3.0 has it fixed).  VAX_COMPILER_FLT_BUG is defined for pcc which
  130. ! # doesn't know how to convert an unsigned long into a float/double
  131.   #DEFINES= -DVAX_COMPILER_FLT_BUG -DNOSWAP
  132.   
  133.   CFLAGS= -O ${DEFINES} ${FEATURES} ${INCPATH}
  134.   #
  135.   # Header files
  136. --- 100,116 ----
  137.   # for Sun
  138.   #DEFINES= -DSUN_FLT_BUG
  139.   
  140. ! # for Ultrix 2.0/2.2
  141.   # don't forget to fix the broken definition of inet_addr in netdb.h
  142.   # it should be declared as a u_long not a in_addr  (the doc is wrong also)
  143. ! # VAX_COMPILER_FLT_BUG is defined for pcc which doesn't know how to 
  144. ! # convert an unsigned long into a float/double
  145.   #DEFINES= -DVAX_COMPILER_FLT_BUG -DNOSWAP
  146.   
  147. + #
  148. + # for a NeXT system, define these pre-processor symbols.
  149. + #DEFINES=-DSUN_FLT_BUG -DGENERIC_UNS_BUG 
  150.   CFLAGS= -O ${DEFINES} ${FEATURES} ${INCPATH}
  151.   #
  152.   # Header files
  153. ***************
  154. *** 108,121 ****
  155.   
  156.   # Source files
  157.   #
  158. ! SRCS=    ntp.c ntpd.c ntpdc.c ntpsubs.c ntp_proto.c ntp_sock.c ntp_adjust.c
  159. ! NTPDSRC= ntpd.c ntpsubs.c ntp_proto.c ntp_sock.c ntp_adjust.c
  160.   
  161.   # Object files
  162.   #
  163. ! OBJS=    ntp.o ntpd.o ntpdc.o ntpsubs.o ntp_proto.o ntp_sock.o ntp_adjust.o
  164. ! NTPDOBJ= ntpd.o ntpsubs.o ntp_proto.o ntp_sock.o ntp_adjust.o
  165.   
  166.   DIST= README Makefile man ${SRCS} ${HDRS} ntp.conf test.c extract.pl stat.pl
  167.   PROGS=    ntp ntpd ntpdc ntest
  168.   
  169. --- 119,135 ----
  170.   
  171.   # Source files
  172.   #
  173. ! NTPDSRC= ntpd.c ntpsubs.c ntp_proto.c ntp_sock.c ntp_adjust.c read_local.c \
  174. !     read_psti.c
  175. ! SRCS=    ntp.c ntpdc.c ${NTPDSRC}
  176.   
  177.   # Object files
  178.   #
  179. ! NTPDOBJ= ntpd.o ntpsubs.o ntp_proto.o ntp_sock.o ntp_adjust.o read_local.o \
  180. !     read_psti.o
  181. ! OBJS=    ntp.o ntpdc.o ${NTPDOBJ}
  182.   
  183.   DIST= README Makefile man ${SRCS} ${HDRS} ntp.conf test.c extract.pl stat.pl
  184.   PROGS=    ntp ntpd ntpdc ntest
  185.   
  186. ***************
  187. *** 126,133 ****
  188.       ${CC} ${LDFLAGS} -o ntp ntp.o ntpsubs.o ${LIBS}
  189.   
  190.   ntpd:    ${NTPDOBJ}
  191. !     ${CC} ${LDFLAGS} -o ntpd ntpd.o ntpsubs.o ntp_adjust.o ntp_proto.o \
  192. !         ntp_sock.o ${LIBS}
  193.   
  194.   ntpdc: ntpdc.o
  195.       ${CC} ${LDFLAGS} -o ntpdc ntpdc.o ${LIBS}
  196. --- 140,146 ----
  197.       ${CC} ${LDFLAGS} -o ntp ntp.o ntpsubs.o ${LIBS}
  198.   
  199.   ntpd:    ${NTPDOBJ}
  200. !     ${CC} ${LDFLAGS} -o ntpd ${NTPDOBJ} ${LIBS}
  201.   
  202.   ntpdc: ntpdc.o
  203.       ${CC} ${LDFLAGS} -o ntpdc ntpdc.o ${LIBS}
  204.  
  205. Index: README
  206. *** README.old    Thu May 18 18:38:20 1989
  207. --- README    Thu May 18 18:38:28 1989
  208. ***************
  209. *** 1,4 ****
  210. ! README for UNIX NTP release $Date: 89/05/03 15:08:58 $ $Revision: 3.4.1.5 $
  211.   
  212.   
  213.   
  214. --- 1,4 ----
  215. ! README for UNIX NTP release $Date: 89/05/18 12:43:58 $ $Revision: 3.4.1.6 $
  216.   
  217.   
  218.   
  219. ***************
  220. *** 36,41 ****
  221. --- 36,42 ----
  222.           VAX:    5
  223.           Sun3:    10
  224.           Sun4:    5
  225. +         NeXT:    7
  226.   
  227.           This step is optional; new algorithms will allow you to
  228.           get by (with reduced accuracy) with the system supplied
  229. ***************
  230. *** 48,53 ****
  231. --- 49,76 ----
  232.       7) Fire up ntpd in /etc/rc.local
  233.   
  234.   History:
  235. + 5/17/89
  236. +     Yet another preprocessor define for broken unsigned long to double
  237. +     conversions.  Define GENERIC_UNS_BUG, and the unsigned long is shifted
  238. +     right one bit and cast to an int before conversion to a double.  This
  239. +     seems to work much better.
  240. +     Preliminary support for NeXT systems.  Be sure to define both
  241. +     GENERIC_UNS_BUG and SUN_FLT_BUG.  The default value of tickadj in the
  242. +     kernel is too large so you'll have to adjust it by using the
  243. +     -t option and compiling with SETTICKADJ.  I don't think you can use
  244. +     gdb on the running /dev/mem image.   NOTE: don't even think of trying
  245. +     to run this on the 0.8 release of the system software.  You will
  246. +     utterly and absolutely hang you system.  Current testing is being 
  247. +     done on the 0.9 release.  So far, there seems to be some weirdness in
  248. +     the kernel which is attempting to sync to the clock to the internal
  249. +     clock chip every so ofter.  So while it compiles and runs, it really
  250. +     doesn't work very well on the NeXT machine.
  251. +     Integration of the reference clock code from Doug Kingston and Jeff 
  252. +     Schiller has been done.  To configure a reference clock, check the
  253. +     ntpd manual page.
  254.   5/3/89
  255.       The changes to the ntp_proto.c module for clockhopper suppression have
  256.       been tweaked once more, ever so slightly to conform with the 21 April
  257.  
  258. Index: ntp.c
  259. *** ntp.c.old    Thu May 18 18:38:44 1989
  260. --- ntp.c    Thu May 18 18:38:50 1989
  261. ***************
  262. *** 1,9 ****
  263.   #ifndef    lint
  264. ! static char *rcsid = "$Source: /usr/users/louie/ntp/RCS/ntp.c,v $ $Revision: 3.4.1.5 $ $Date: 89/05/03 15:09:53 $";
  265.   #endif    lint
  266.   
  267.   /*
  268.    *  $Log:    ntp.c,v $
  269.    * Revision 3.4.1.5  89/05/03  15:09:53  louie
  270.    * Fix minor problem in ntp.c to get sin_family set in the proper place.
  271.    * 
  272. --- 1,13 ----
  273.   #ifndef    lint
  274. ! static char *rcsid = "$Source: /usr/users/louie/ntp/RCS/ntp.c,v $ $Revision: 3.4.1.6 $ $Date: 89/05/18 18:21:29 $";
  275.   #endif    lint
  276.   
  277.   /*
  278.    *  $Log:    ntp.c,v $
  279. +  * Revision 3.4.1.6  89/05/18  18:21:29  louie
  280. +  * A few cosmetic changes in ntp.c for the case when udp/ntp is not in the
  281. +  * /etc/services file.
  282. +  * 
  283.    * Revision 3.4.1.5  89/05/03  15:09:53  louie
  284.    * Fix minor problem in ntp.c to get sin_family set in the proper place.
  285.    * 
  286. ***************
  287. *** 79,84 ****
  288. --- 83,89 ----
  289.    */
  290.   
  291.   #include <stdio.h>
  292. + #include <sys/types.h>
  293.   #include <sys/param.h>
  294.   #include <sys/time.h>
  295.   #include <sys/uio.h>
  296. ***************
  297. *** 136,142 ****
  298.       double t1, t2, t3, t4, offset, delay;
  299.       char ref_clock[5];
  300.       time_t net_time;
  301. !     ref_clock[4] = NULL;
  302.   
  303.       timeout.tv_sec = TIME_OUT;
  304.       timeout.tv_usec = 0;
  305. --- 141,147 ----
  306.       double t1, t2, t3, t4, offset, delay;
  307.       char ref_clock[5];
  308.       time_t net_time;
  309. !     ref_clock[4] = '\0';
  310.   
  311.       timeout.tv_sec = TIME_OUT;
  312.       timeout.tv_usec = 0;
  313. ***************
  314. *** 144,150 ****
  315.   
  316.       sp = getservbyname("ntp", "udp");
  317.       if (sp == NULL) {
  318. !         fprintf(stderr, "udp/ntp: service unknown\nUsing default %d\n",
  319.               NTP_PORT);
  320.           dst.sin_port = htons(NTP_PORT);
  321.       } else
  322. --- 149,155 ----
  323.   
  324.       sp = getservbyname("ntp", "udp");
  325.       if (sp == NULL) {
  326. !         fprintf(stderr, "udp/ntp: service unknown; using default %d\n",
  327.               NTP_PORT);
  328.           dst.sin_port = htons(NTP_PORT);
  329.       } else
  330.  
  331. Index: ntp.h
  332. *** ntp.h.old    Thu May 18 18:39:13 1989
  333. --- ntp.h    Thu May 18 18:39:19 1989
  334. ***************
  335. *** 1,7 ****
  336. ! /* $Source: /usr/users/louie/ntp/RCS/ntp.h,v $ $Revision: 3.4.1.6 $ $Date: 89/05/03 15:11:06 $ */
  337.   
  338.   /*
  339.    *  $Log:    ntp.h,v $
  340.    * Revision 3.4.1.6  89/05/03  15:11:06  louie
  341.    * Specify default file for drift value and more peer flag definitions to
  342.    * reflect various stages of clock selection critera.
  343. --- 1,10 ----
  344. ! /* $Source: /usr/users/louie/ntp/RCS/ntp.h,v $ $Revision: 3.4.1.7 $ $Date: 89/05/18 18:22:14 $ */
  345.   
  346.   /*
  347.    *  $Log:    ntp.h,v $
  348. +  * Revision 3.4.1.7  89/05/18  18:22:14  louie
  349. +  * A few extra diddles in ntp.h for the reference clock feature.
  350. +  * 
  351.    * Revision 3.4.1.6  89/05/03  15:11:06  louie
  352.    * Specify default file for drift value and more peer flag definitions to
  353.    * reflect various stages of clock selection critera.
  354. ***************
  355. *** 136,141 ****
  356. --- 139,148 ----
  357.   #define    NTP_MAXAGE    86400
  358.   #define    NTP_MAXSKW    0.01    /* seconds */
  359.   #define    NTP_MINDIST    0.02    /* seconds */
  360. + #ifdef    REFCLOCK
  361. + #define    NTP_REFMAXSKW    0.001    /* seconds (for REFCLOCKs) */
  362. + #define    NTP_REFMINDIST    0.001    /* seconds (for REFCLOCKs) */
  363. + #endif
  364.   #define    NTP_MINPOLL    6    /* (64) seconds between messages */
  365.   #define    NTP_MAXPOLL    10    /* (1024) secs to poll */
  366.   #define    NTP_WINDOW    8    /* size of shift register */
  367. ***************
  368. *** 297,302 ****
  369. --- 304,310 ----
  370.   #define    PEER_FL_CANDIDATE    0x0200    /* candidate peer */
  371.   #define    PEER_FL_SYNC        0x1000    /* peer can bet sync'd to */
  372.   #define    PEER_FL_BCAST        0x2000    /* broadcast peer */
  373. + #define    PEER_FL_REFCLOCK    0x4000    /* peer is a local reference clock */
  374.   #define    PEER_FL_SELECTED    0x8000    /* actually used by query routine */
  375.   
  376.       int    sock;            /* index into sockets to derive
  377.  
  378. Index: ntp_adjust.c
  379. *** ntp_adjust.c.old    Thu May 18 18:39:29 1989
  380. --- ntp_adjust.c    Thu May 18 18:39:32 1989
  381. ***************
  382. *** 1,5 ****
  383.   #ifndef lint
  384. ! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntp_adjust.c,v $ $Revision: 3.4.1.3 $ $Date: 89/04/07 18:05:17 $";
  385.   #endif
  386.   
  387.   /*
  388. --- 1,5 ----
  389.   #ifndef lint
  390. ! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntp_adjust.c,v $ $Revision: 3.4.1.4 $ $Date: 89/05/18 18:23:36 $";
  391.   #endif
  392.   
  393.   /*
  394. ***************
  395. *** 7,12 ****
  396. --- 7,15 ----
  397.    * 5. of the NTP specification.
  398.    *
  399.    * $Log:    ntp_adjust.c,v $
  400. +  * Revision 3.4.1.4  89/05/18  18:23:36  louie
  401. +  * A couple of changes to debug NeXT support in ntp_adjust.c
  402. +  * 
  403.    * Revision 3.4.1.3  89/04/07  18:05:17  louie
  404.    * Removed unused variable from ntp_adjust.c module.
  405.    * 
  406. ***************
  407. *** 58,63 ****
  408. --- 61,67 ----
  409.    */
  410.   
  411.   #include <stdio.h>
  412. + #include <sys/types.h>
  413.   #include <sys/param.h>
  414.   #include <sys/socket.h>
  415.   #include <sys/time.h>
  416. ***************
  417. *** 132,138 ****
  418.   adj_logical(offset)
  419.       double offset;
  420.   {
  421. !     struct timeval tv2;
  422.   #ifdef    XADJTIME2
  423.       struct timeval delta, olddelta;
  424.   #endif
  425. --- 136,142 ----
  426.   adj_logical(offset)
  427.       double offset;
  428.   {
  429. !     struct timeval tv1, tv2;
  430.   #ifdef    XADJTIME2
  431.       struct timeval delta, olddelta;
  432.   #endif
  433. ***************
  434. *** 150,158 ****
  435.           (void) gettimeofday(&tv2, (struct timezone *) 0);
  436.           steptime += tv2.tv_sec;
  437.           steptime += tv2.tv_usec / 1000000.0;
  438. !         tv2.tv_sec = steptime;
  439. !         tv2.tv_usec = (steptime - tv2.tv_sec) * 1000000;
  440. !         if (settimeofday(&tv2, (struct timezone *) 0) < 0) {
  441.               syslog(LOG_ERR, "Can't set time: %m");
  442.               return(-1);
  443.           }
  444. --- 154,169 ----
  445.           (void) gettimeofday(&tv2, (struct timezone *) 0);
  446.           steptime += tv2.tv_sec;
  447.           steptime += tv2.tv_usec / 1000000.0;
  448. !         tv1.tv_sec = steptime;
  449. !         tv1.tv_usec = (steptime - tv1.tv_sec) * 1000000;
  450. ! #ifdef    DEBUG
  451. !         if (debug > 2) {
  452. !             steptime = (tv1.tv_sec + tv1.tv_usec/1000000.0) -
  453. !                 (tv2.tv_sec + tv2.tv_usec/1000000.0);
  454. !             printf("adj_logical: %f %f\n", offset, steptime);
  455. !         }
  456. ! #endif
  457. !         if (settimeofday(&tv1, (struct timezone *) 0) < 0) {
  458.               syslog(LOG_ERR, "Can't set time: %m");
  459.               return(-1);
  460.           }
  461.  
  462. Index: ntp_proto.c
  463. *** ntp_proto.c.old    Thu May 18 18:40:21 1989
  464. --- ntp_proto.c    Thu May 18 18:40:45 1989
  465. ***************
  466. *** 1,5 ****
  467.   #ifndef    lint
  468. ! static char *rcsid = "$Source: /usr/users/louie/ntp/RCS/ntp_proto.c,v $ $Revision: 3.4.1.11 $ $Date: 89/05/03 23:51:30 $";
  469.   #endif
  470.   
  471.   /*
  472. --- 1,5 ----
  473.   #ifndef    lint
  474. ! static char *rcsid = "$Source: /usr/users/louie/ntp/RCS/ntp_proto.c,v $ $Revision: 3.4.1.12 $ $Date: 89/05/18 18:25:04 $";
  475.   #endif
  476.   
  477.   /*
  478. ***************
  479. *** 11,16 ****
  480. --- 11,19 ----
  481.   
  482.   /*
  483.    * $Log:    ntp_proto.c,v $
  484. +  * Revision 3.4.1.12  89/05/18  18:25:04  louie
  485. +  * Changes for reference clock feature in ntp_proto.c
  486. +  * 
  487.    * Revision 3.4.1.11  89/05/03  23:51:30  louie
  488.    * Had my head on backwards with a reversed test in the clockhopper avoidance
  489.    * code.  Need to switch to the first selected clock when its stratum is lower
  490. ***************
  491. *** 108,113 ****
  492. --- 111,117 ----
  493.    */
  494.   
  495.   #include <stdio.h>
  496. + #include <sys/types.h>
  497.   #include <sys/param.h>
  498.   #include <sys/uio.h>
  499.   #include <sys/socket.h>
  500. ***************
  501. *** 150,157 ****
  502.   extern void make_new_peer(), double_to_s_fixed(), tstamp(), demobilize();
  503.       
  504.   
  505.   void    process_packet(), clock_update(), clear(), clock_filter(),
  506. !     select_clock(), poll_update();
  507.   
  508.   /* 3.4. Event Processing */
  509.   
  510. --- 154,165 ----
  511.   extern void make_new_peer(), double_to_s_fixed(), tstamp(), demobilize();
  512.       
  513.   
  514. + #ifdef    REFCLOCK
  515. + void    refclock_input();
  516. + #endif
  517.   void    process_packet(), clock_update(), clear(), clock_filter(),
  518. !     receive(), select_clock(), poll_update();
  519.   
  520.   /* 3.4. Event Processing */
  521.   
  522. ***************
  523. *** 194,200 ****
  524.   
  525.       peer->xmt = pkt->xmt;
  526.   
  527. !     if ((peer->flags & PEER_FL_BCAST) == 0) {
  528.           /* select correct socket to send reply on */
  529.           if (sendto(addrs[(peer->sock < 0 ? 0 : peer->sock)].fd,
  530.                  (char *) pkt, sizeof(ntpframe),
  531. --- 202,208 ----
  532.   
  533.       peer->xmt = pkt->xmt;
  534.   
  535. !     if ((peer->flags & (PEER_FL_BCAST|PEER_FL_REFCLOCK)) == 0) {
  536.           /* select correct socket to send reply on */
  537.           if (sendto(addrs[(peer->sock < 0 ? 0 : peer->sock)].fd,
  538.                  (char *) pkt, sizeof(ntpframe),
  539. ***************
  540. *** 203,208 ****
  541. --- 211,251 ----
  542.                      ntoa(peer->src.sin_addr));
  543.               return;
  544.           }
  545. + #ifdef    REFCLOCK
  546. +     } else if (peer->flags & PEER_FL_REFCLOCK) {
  547. +         /* Special version of code below, adjusted for refclocks */
  548. +         peer->pkt_sent++;
  549. +         i = peer->reach;    /* save a copy */
  550. +         peer->reach = (peer->reach << 1) & NTP_WINDOW_SHIFT_MASK;
  551. +         if (i && peer->reach == 0) {
  552. +             syslog(LOG_INFO, "Lost reachability with %.4s",
  553. +                    (char *)&peer->refid);
  554. + #ifdef    DEBUG
  555. +             if (debug)
  556. +                 printf("Lost reachability with %.4s\n",
  557. +                        (char *)&peer->refid);
  558. + #endif
  559. +         }
  560. +         if (peer->reach == 0)
  561. +             clear(peer);
  562. +         if (peer->valid < 2)
  563. +             peer->valid++;
  564. +         else {
  565. +             clock_filter(peer, 0.0, 0.0);    /* call with invalid values */
  566. +             select_clock();        /* and try to reselect clock */
  567. +         }
  568. +         peer->timer = 1<<NTP_MINPOLL;    /* poll refclocks frequently */
  569. +         refclock_input(peer, pkt);
  570. +         return;
  571. + #endif REFCLOCK
  572.       } else {
  573.   #ifdef    BROADCAST_NTP
  574.           if (sendto(addrs[peer->sock].fd,
  575. ***************
  576. *** 270,275 ****
  577. --- 313,353 ----
  578.           poll_update(peer, peer->hpoll + 1);
  579.   }
  580.   
  581. + #ifdef REFCLOCK
  582. + void
  583. + refclock_input(peer, pkt)
  584. +     struct ntpdata *pkt;
  585. +     struct ntp_peer *peer;
  586. + {
  587. +     struct timeval *tvp;
  588. +     struct timeval *otvp;
  589. +     if (read_clock(peer->sock, &tvp, &otvp))
  590. +         return;
  591. +     tstamp(&pkt->rec, tvp);
  592. +     pkt->xmt = pkt->rec;
  593. +     pkt->reftime = pkt->rec;
  594. +     tstamp(&pkt->org, otvp);
  595. +     peer->xmt = pkt->org;
  596. +     pkt->refid = peer->refid;
  597. +     pkt->status &= ~ALARM;
  598. +     pkt->stratum = peer->stratum;
  599. +     pkt->ppoll = 0xff;
  600. +     pkt->precision = peer->precision;
  601. +     double_to_s_fixed(&pkt->distance, 0.0);
  602. +     double_to_s_fixed(&pkt->dispersion, 0.0);
  603. + #ifdef    DEBUG
  604. +     if (debug > 5) {
  605. +         printf("\nFaking packet ");
  606. +         dump_pkt(&peer->src, pkt, (struct ntp_peer *)NULL);
  607. +     }
  608. + #endif
  609. +     receive((struct sockaddr_in *)peer, pkt, otvp, -1);
  610. +     return;
  611. + }
  612. + #endif REFCLOCK
  613.   /* 3.4.2. Receive Procedure */
  614.   void
  615.   receive(dst, pkt, tvp, sock)
  616. ***************
  617. *** 300,306 ****
  618.       /* if we're only going to support NTP Version 2 then this stuff
  619.          isn't necessary, right? */
  620.   
  621. !     if ((peer_mode = pkt->status & MODEMASK) == 0) {
  622.           /* packet from an older NTP implementation.  Synthesize the
  623.              correct mode.  The mapping goes like this:
  624.   
  625. --- 378,384 ----
  626.       /* if we're only going to support NTP Version 2 then this stuff
  627.          isn't necessary, right? */
  628.   
  629. !     if ((peer_mode = pkt->status & MODEMASK) == 0 && dst) {
  630.           /* packet from an older NTP implementation.  Synthesize the
  631.              correct mode.  The mapping goes like this:
  632.   
  633. ***************
  634. *** 337,342 ****
  635. --- 415,425 ----
  636.           peer->hmode = MODE_SYM_PAS;
  637.           peer->reach = 0;
  638.           clear(peer);
  639. + #ifdef    REFCLOCK
  640. +     } else if (sock == -1) {
  641. +         /* we're begin called by refclock_input(), get peer ptr */
  642. +         peer = (struct ntp_peer *)dst;
  643. + #endif
  644.       } else
  645.           peer = check_peer(dst, sock);
  646.   
  647. ***************
  648. *** 515,521 ****
  649.       delay = (t2 - t1) - (t3 - t4);
  650.       offset = ((t2 - t1) + (t3 - t4)) / 2.0;
  651.   
  652. !     delay += NTP_MAXSKW + 1.0/(unsigned long)(1L << -sys.precision);
  653.       if (peer->precision < 0 && -peer->precision < sizeof(long)*NBBY)
  654.           delay += 1.0/(unsigned long)(1L << -peer->precision);
  655.   
  656. --- 598,609 ----
  657.       delay = (t2 - t1) - (t3 - t4);
  658.       offset = ((t2 - t1) + (t3 - t4)) / 2.0;
  659.   
  660. !     delay += 1.0/(unsigned long)(1L << -sys.precision)
  661. ! #ifndef    REFCLOCK
  662. !         + NTP_MAXSKW;
  663. ! #else
  664. !         + (peer->flags&PEER_FL_REFCLOCK) ? NTP_REFMAXSKW : NTP_MAXSKW;
  665. ! #endif
  666.       if (peer->precision < 0 && -peer->precision < sizeof(long)*NBBY)
  667.           delay += 1.0/(unsigned long)(1L << -peer->precision);
  668.   
  669. ***************
  670. *** 524,530 ****
  671. --- 612,623 ----
  672.           return;
  673.       }
  674.   
  675. + #ifndef    REFCLOCK
  676.       delay = MAX(delay, NTP_MINDIST);
  677. + #else
  678. +     delay = MAX(delay, (peer->flags & PEER_FL_REFCLOCK) ?
  679. +             NTP_REFMINDIST : NTP_MINDIST);
  680. + #endif
  681.   
  682.       peer->valid = 0;
  683.       clock_filter(peer, delay, offset);  /* invoke clock filter procedure */
  684. ***************
  685. *** 531,537 ****
  686.   #ifdef    DEBUG
  687.       if (debug) {
  688.           printf("host: %s : %f : %f : %f : %f : %f : %o\n",
  689. !                ntoa(dst->sin_addr), delay, offset,
  690.                  peer->estdelay, peer->estoffset, peer->estdisp,
  691.                  peer->reach);
  692.       }
  693. --- 624,631 ----
  694.   #ifdef    DEBUG
  695.       if (debug) {
  696.           printf("host: %s : %f : %f : %f : %f : %f : %o\n",
  697. !                dst ? ntoa(dst->sin_addr) : "refclock",
  698. !                delay, offset,
  699.                  peer->estdelay, peer->estoffset, peer->estdisp,
  700.                  peer->reach);
  701.       }
  702. ***************
  703. *** 576,582 ****
  704. --- 670,690 ----
  705.            *  Update the local system variables
  706.            */
  707.           sys.leap = peer->leap;
  708. + #ifndef    REFCLOCK
  709.           sys.stratum = peer->stratum + 1;
  710. +         sys.refid = peer->src.sin_addr.s_addr;
  711. + #else
  712. +         if (peer->flags & PEER_FL_REFCLOCK) {
  713. +             /* once we re-map the stratums so that stratum 0 is
  714. +                better than stratum 1, some of this foolishness
  715. +                can go away */
  716. +             sys.stratum = peer->stratum;
  717. +             sys.refid = peer->refid;
  718. +         } else {
  719. +             sys.stratum = peer->stratum + 1;
  720. +             sys.refid = peer->src.sin_addr.s_addr;
  721. +         }
  722. + #endif
  723.   
  724.           temp = s_fixed_to_double(&peer->distance) + peer->estdelay;
  725.           double_to_s_fixed(&sys.distance, temp);
  726. ***************
  727. *** 584,590 ****
  728.           temp = s_fixed_to_double(&peer->dispersion) + peer->estdisp;
  729.           double_to_s_fixed(&sys.dispersion, temp);
  730.   
  731. -         sys.refid = peer->src.sin_addr.s_addr;
  732.           sys.reftime = peer->rec;
  733.   
  734.   #ifdef    DEBUG
  735. --- 692,697 ----
  736. ***************
  737. *** 714,719 ****
  738. --- 821,830 ----
  739.       interval = 1 << (MAX(MIN(peer->ppoll, MIN(peer->hpoll, NTP_MAXPOLL)),
  740.                  NTP_MINPOLL));
  741.   
  742. + #ifdef    REFCLOCK
  743. +     if (peer->flags & PEER_FL_REFCLOCK)
  744. +         interval = 1 << NTP_MINPOLL;
  745. + #endif
  746.       if (interval == peer->timer)
  747.           return;
  748.   
  749.  
  750. Index: ntp_sock.c
  751. *** ntp_sock.c.old    Thu May 18 18:41:07 1989
  752. --- ntp_sock.c    Thu May 18 18:41:09 1989
  753. ***************
  754. *** 1,9 ****
  755.   #ifndef    lint
  756. ! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntp_sock.c,v $ $Revision: 3.4.1.2 $ $Date: 89/04/07 19:07:46 $";
  757.   #endif
  758.   
  759.   /*
  760.    * $Log:    ntp_sock.c,v $
  761.    * Revision 3.4.1.2  89/04/07  19:07:46  louie
  762.    * Deleted unused variables in ntp_sock.c
  763.    * 
  764. --- 1,16 ----
  765.   #ifndef    lint
  766. ! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntp_sock.c,v $ $Revision: 3.4.1.3 $ $Date: 89/05/18 18:28:20 $";
  767.   #endif
  768.   
  769.   /*
  770.    * $Log:    ntp_sock.c,v $
  771. +  * Revision 3.4.1.3  89/05/18  18:28:20  louie
  772. +  * In ntp_sock.c, change the order that the bind() call is done for each socket.
  773. +  * It turns out that if you have the Multicast code installed, incoming packets
  774. +  * will be delived to the *first* socket that matches.  It also turns out that
  775. +  * when binding sockets, the first one bound is the last on checked, so we want
  776. +  * to bind the wildcard socket first.
  777. +  * 
  778.    * Revision 3.4.1.2  89/04/07  19:07:46  louie
  779.    * Deleted unused variables in ntp_sock.c
  780.    * 
  781. ***************
  782. *** 38,43 ****
  783. --- 45,51 ----
  784.    * 
  785.    */
  786.   
  787. + #include <sys/types.h>
  788.   #include <sys/param.h>
  789.   #include <sys/ioctl.h>
  790.   #include <sys/file.h>
  791. ***************
  792. *** 261,267 ****
  793.       }
  794.       close(vs);
  795.   
  796. !     for (i = nintf - 1; i >= 0; i--) {
  797.           /* create a datagram (UDP) socket */
  798.           if ((addrs[i].fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  799.               syslog(LOG_ERR, "socket() failed: %m");
  800. --- 269,275 ----
  801.       }
  802.       close(vs);
  803.   
  804. !     for (i = 0; i < nintf; i++) {
  805.           /* create a datagram (UDP) socket */
  806.           if ((addrs[i].fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  807.               syslog(LOG_ERR, "socket() failed: %m");
  808. ***************
  809. *** 315,321 ****
  810.            *  is being bound anyway..
  811.            */
  812.           if (setsockopt(addrs[i].fd, SOL_SOCKET, SO_REUSEADDR,
  813.                      (char *)&off, sizeof(off))) {
  814.               syslog(LOG_ERR, "setsockopt SO_REUSEADDR off fails: %m");
  815.   #ifdef    TEST
  816. --- 323,328 ----
  817.  
  818. Index: ntpd.c
  819. *** ntpd.c.old    Thu May 18 18:41:45 1989
  820. --- ntpd.c    Thu May 18 18:42:02 1989
  821. ***************
  822. *** 1,9 ****
  823.   #ifndef    lint
  824. ! static char *rcsid = "$Source: /usr/users/louie/ntp/RCS/ntpd.c,v $ $Revision: 3.4.1.8 $ $Date: 89/05/03 15:16:17 $";
  825.   #endif    lint
  826.   
  827.   /*
  828.    *  $Log:    ntpd.c,v $
  829.    * Revision 3.4.1.8  89/05/03  15:16:17  louie
  830.    * Add code to save the value of the drift compensation register to a file every
  831.    * hour.  Add additional configuration file directives which can specify the same
  832. --- 1,13 ----
  833.   #ifndef    lint
  834. ! static char *rcsid = "$Source: /usr/users/louie/ntp/RCS/ntpd.c,v $ $Revision: 3.4.1.9 $ $Date: 89/05/18 18:30:17 $";
  835.   #endif    lint
  836.   
  837.   /*
  838.    *  $Log:    ntpd.c,v $
  839. +  * Revision 3.4.1.9  89/05/18  18:30:17  louie
  840. +  * Changes in ntpd.c for reference clock support.  Also, a few diddles to
  841. +  * accomodate the NeXT computer system that has a slightly different nlist.h
  842. +  * 
  843.    * Revision 3.4.1.8  89/05/03  15:16:17  louie
  844.    * Add code to save the value of the drift compensation register to a file every
  845.    * hour.  Add additional configuration file directives which can specify the same
  846. ***************
  847. *** 78,83 ****
  848. --- 82,88 ----
  849.    */
  850.   
  851.   #include <stdio.h>
  852. + #include <sys/types.h>
  853.   #include <sys/param.h>
  854.   #include <sys/uio.h>
  855.   #include <sys/socket.h>
  856. ***************
  857. *** 282,293 ****
  858.           setlogmask(LOG_UPTO(LOG_INFO));
  859.   #endif    /* LOG_DAEMON */
  860.   
  861. !     syslog(LOG_NOTICE, "%s version $Revision: 3.4.1.8 $", prog_name);
  862.       syslog(LOG_NOTICE, "patchlevel %d", PATCHLEVEL);
  863.   
  864.   #ifdef    DEBUG
  865.       if (debug)
  866. !         printf("%s version $Revision: 3.4.1.8 $ patchlevel %d\n",
  867.                  prog_name, PATCHLEVEL);
  868.   #endif
  869.       (void) setpriority(PRIO_PROCESS, 0, -10);
  870. --- 287,298 ----
  871.           setlogmask(LOG_UPTO(LOG_INFO));
  872.   #endif    /* LOG_DAEMON */
  873.   
  874. !     syslog(LOG_NOTICE, "%s version $Revision: 3.4.1.9 $", prog_name);
  875.       syslog(LOG_NOTICE, "patchlevel %d", PATCHLEVEL);
  876.   
  877.   #ifdef    DEBUG
  878.       if (debug)
  879. !         printf("%s version $Revision: 3.4.1.9 $ patchlevel %d\n",
  880.                  prog_name, PATCHLEVEL);
  881.   #endif
  882.       (void) setpriority(PRIO_PROCESS, 0, -10);
  883. ***************
  884. *** 459,465 ****
  885.       struct ntpdata *pkt;
  886.       struct ntp_peer *peer;
  887.   {
  888. -     char ref_clock[5];
  889.       struct in_addr clock_host;
  890.   
  891.       printf("Packet: [%s](%d)\n", inet_ntoa(dst->sin_addr),
  892. --- 464,469 ----
  893. ***************
  894. *** 471,479 ****
  895.       switch (pkt->stratum) {
  896.       case 0:
  897.       case 1:
  898. !         (void) strncpy(ref_clock, (char *) &pkt->refid, 4);
  899. !         ref_clock[4] = '\0';
  900. !         printf(" (%s)\n", ref_clock);
  901.           break;
  902.       default:
  903.           clock_host.s_addr = (u_long) pkt->refid;
  904. --- 475,481 ----
  905.       switch (pkt->stratum) {
  906.       case 0:
  907.       case 1:
  908. !         printf(" (%.4s)\n", (char *)&pkt->refid);
  909.           break;
  910.       default:
  911.           clock_host.s_addr = (u_long) pkt->refid;
  912. ***************
  913. *** 867,872 ****
  914. --- 869,943 ----
  915.               }
  916.               if (fscanf(fp, "%s", name) != 1)
  917.                   error = TRUE;
  918. + #ifdef REFCLOCK
  919. +             else if (name[0] == '/') {
  920. +                 int stratum, precision;
  921. +                 char clk_type[20];
  922. +                 if (fscanf(fp, "%4s", ref_clock) != 1) {
  923. +                     error = TRUE;
  924. +                     syslog(LOG_ERR, "reference id missing");
  925. +                     goto skipit;
  926. +                 }
  927. +                 if (fscanf(fp, "%4d", &stratum) != 1) {
  928. +                     error = TRUE;
  929. +                     syslog(LOG_ERR, "reference stratum missing");
  930. +                     goto skipit;
  931. +                 }
  932. +                 if (fscanf(fp, "%4d", &precision) != 1) {
  933. +                     error = TRUE;
  934. +                     syslog(LOG_ERR, "reference precision missing");
  935. +                     goto skipit;
  936. +                 }
  937. +                 if (fscanf(fp, "%19s", clk_type) != 1) {
  938. +                     error = TRUE;
  939. +                     syslog(LOG_ERR, "reference type missing");
  940. +                     goto skipit;
  941. +                 }
  942. +                 if((i = init_clock(name, clk_type)) < 0) {
  943. +                     /* If we could not initialize clock line */
  944. + #ifdef DEBUG
  945. +                     if (debug)
  946. +                         printf("Could not init reference source %s (type %s)\n",
  947. +                             name, clk_type);
  948. +                     else
  949. + #endif DEBUG
  950. +                         syslog(LOG_ERR, "Could not init reference source %s (type %s)",
  951. +                             name, clk_type);
  952. +                     error = TRUE;
  953. +                     goto skipit;
  954. +                 }
  955. +                 peer = (struct ntp_peer *)
  956. +                     malloc(sizeof(struct ntp_peer));
  957. +                 if (peer == NULL) {
  958. +                     close(i);
  959. +                     error = TRUE;
  960. +                     goto skipit;
  961. +                 }
  962. +                 make_new_peer(peer);
  963. +                 ref_clock[4] = 0;
  964. +                 (void) strncpy((char *) &peer->refid,
  965. +                         ref_clock, 4);
  966. +                 peer->flags = PEER_FL_CONFIG|PEER_FL_REFCLOCK;
  967. +                 peer->hmode = MODE_SYM_ACT;
  968. +                 peer->stopwatch = stagger;
  969. +                 stagger += (1<<CLOCK_ADJ);
  970. +                 peer->flags |= PEER_FL_SYNC;
  971. +                 peer->sock = i;
  972. +                 peer->stratum = stratum;
  973. +                 peer->precision = precision;
  974. +                 clear(peer);
  975. +                 enqueue(&peer_list, peer);
  976. +                 if (debug > 1)
  977. +                     printf("Peer %s mode %d refid %.4s stratum %d precision %d\n",
  978. +                            name,
  979. +                            peer->hmode,
  980. +                            (char *)&peer->refid,
  981. +                            stratum, precision);
  982. +                 transmit(peer);    /* head start for REFCLOCK */
  983. +             }
  984. + #endif REFCLOCK
  985.               else if (GetHostName(name, &sin) == 0)
  986.                   syslog(LOG_ERR, "%s: unknown host", name);
  987.               else {
  988. ***************
  989. *** 875,881 ****
  990.                           sin.sin_addr.s_addr)
  991.                           goto skipit;
  992.   
  993. !                 sin.sin_port = servp->s_port;
  994.                   peer = check_peer(&sin, -1);
  995.                   if (peer == NULL) {
  996.                       peer = (struct ntp_peer *)
  997. --- 946,956 ----
  998.                           sin.sin_addr.s_addr)
  999.                           goto skipit;
  1000.   
  1001. !                 if (servp)
  1002. !                     sin.sin_port = servp->s_port;
  1003. !                 else
  1004. !                     sin.sin_port = htons(NTP_PORT);
  1005.                   peer = check_peer(&sin, -1);
  1006.                   if (peer == NULL) {
  1007.                       peer = (struct ntp_peer *)
  1008. ***************
  1009. *** 952,958 ****
  1010.        *  Read saved drift compensation register value.
  1011.        */
  1012.       if ((fp = fopen(driftcomp_file, "r")) != NULL) {
  1013. !         if (fscanf(fp, "%f", &j) == 1 && j > -1.0 && j < 1.0) {
  1014.               drift_comp = j;
  1015.               syslog(LOG_INFO,
  1016.                      "Drift compensation value initialized to %f", j);
  1017. --- 1027,1033 ----
  1018.        *  Read saved drift compensation register value.
  1019.        */
  1020.       if ((fp = fopen(driftcomp_file, "r")) != NULL) {
  1021. !         if (fscanf(fp, "%lf", &j) == 1 && j > -1.0 && j < 1.0) {
  1022.               drift_comp = j;
  1023.               syslog(LOG_INFO,
  1024.                      "Drift compensation value initialized to %f", j);
  1025. ***************
  1026. *** 972,982 ****
  1027.   init_kern_vars() {
  1028.       int kmem;
  1029.       static char    *memory = "/dev/kmem";
  1030. !     static struct nlist nl[] =
  1031. !     {    {"_tickadj"},
  1032.           {"_hz"},
  1033.           {"_tick"},
  1034.           {""},
  1035.       };
  1036.       static int *kern_vars[] = {&kern_tickadj, &kern_hz, &kern_tick};
  1037.       int i;
  1038. --- 1047,1064 ----
  1039.   init_kern_vars() {
  1040.       int kmem;
  1041.       static char    *memory = "/dev/kmem";
  1042. !     static struct nlist nl[] = {
  1043. ! #ifndef    NeXT
  1044. !         {"_tickadj"},
  1045.           {"_hz"},
  1046.           {"_tick"},
  1047.           {""},
  1048. + #else
  1049. +         {{"_tickadj"}},
  1050. +         {{"_hz"}},
  1051. +         {{"_tick"}},
  1052. +         {{""}},
  1053. + #endif
  1054.       };
  1055.       static int *kern_vars[] = {&kern_tickadj, &kern_hz, &kern_tick};
  1056.       int i;
  1057. ***************
  1058. *** 997,1013 ****
  1059.   
  1060.           if ((where = nl[i].n_value) == 0) {
  1061.               syslog(LOG_ERR, "Unknown kernal var %s",
  1062. !                    nl[i].n_name);
  1063.               continue;
  1064.           }
  1065.           if (lseek(kmem, where, L_SET) == -1) {
  1066.               syslog(LOG_ERR, "lseek for %s fails: %m",
  1067. !                    nl[i].n_name);
  1068.               continue;
  1069.           }
  1070.           if (read(kmem, kern_vars[i], sizeof(int)) != sizeof(int)) {
  1071.               syslog(LOG_ERR, "read for %s fails: %m",
  1072. !                    nl[i].n_name);
  1073.               *kern_vars[i] = 0;
  1074.           }
  1075.       }
  1076. --- 1079,1111 ----
  1077.   
  1078.           if ((where = nl[i].n_value) == 0) {
  1079.               syslog(LOG_ERR, "Unknown kernal var %s",
  1080. ! #ifdef    NeXT
  1081. !                    nl[i].n_un.n_name
  1082. ! #else
  1083. !                    nl[i].n_name
  1084. ! #endif
  1085. !                    );
  1086.               continue;
  1087.           }
  1088.           if (lseek(kmem, where, L_SET) == -1) {
  1089.               syslog(LOG_ERR, "lseek for %s fails: %m",
  1090. ! #ifdef    NeXT
  1091. !                    nl[i].n_un.n_name
  1092. ! #else
  1093. !                    nl[i].n_name
  1094. ! #endif
  1095. !                    );
  1096.               continue;
  1097.           }
  1098.           if (read(kmem, kern_vars[i], sizeof(int)) != sizeof(int)) {
  1099.               syslog(LOG_ERR, "read for %s fails: %m",
  1100. ! #ifdef    NeXT
  1101. !                    nl[i].n_un.n_name
  1102. ! #else
  1103. !                    nl[i].n_name
  1104. ! #endif
  1105. !                    );
  1106.               *kern_vars[i] = 0;
  1107.           }
  1108.       }
  1109. ***************
  1110. *** 1226,1235 ****
  1111.                  drift_comp, compliance, peer_switches,
  1112.                  peer_sw_inhibited);
  1113.   
  1114. !     if (sys.peer == NULL)
  1115.           strcat(buf, " UNSYNC");
  1116. !     else {
  1117.           p = strlen(buf);
  1118.           (void) sprintf(buf + p, " off %f SYNC %s %d",
  1119.                      sys.peer->estoffset,
  1120.                      ntoa(sys.peer->src.sin_addr),
  1121. --- 1324,1341 ----
  1122.                  drift_comp, compliance, peer_switches,
  1123.                  peer_sw_inhibited);
  1124.   
  1125. !     if (sys.peer == NULL) {
  1126.           strcat(buf, " UNSYNC");
  1127. ! #ifdef    REFCLOCK
  1128. !     } else if (sys.peer->flags & PEER_FL_REFCLOCK) {
  1129.           p = strlen(buf);
  1130. +         (void) sprintf(buf + p, " off %f SYNC %.4s %d",
  1131. +                    sys.peer->estoffset,
  1132. +                    (char *)&sys.peer->refid,
  1133. +                    sys.peer->stratum);
  1134. + #endif
  1135. +     } else {
  1136. +         p = strlen(buf);
  1137.           (void) sprintf(buf + p, " off %f SYNC %s %d",
  1138.                      sys.peer->estoffset,
  1139.                      ntoa(sys.peer->src.sin_addr),
  1140. ***************
  1141. *** 1306,1309 ****
  1142. --- 1412,1471 ----
  1143.   #endif
  1144.       exit(1);
  1145.   }
  1146. + #ifdef    REFCLOCK
  1147. + struct refclock {
  1148. +     int fd;
  1149. +     int (*reader)();
  1150. +     struct refclock *next;
  1151. + } *refclocks = NULL;
  1152.   
  1153. + int init_clock_local(), read_clock_local();
  1154. + #ifdef PSTI
  1155. + int init_clock_psti(), read_clock_psti();
  1156. + #endif PSTI
  1157. + init_clock(name, type)
  1158. + char *name, *type;
  1159. + {
  1160. +     struct refclock *r;
  1161. +     int (*reader)();
  1162. +     int cfd;
  1163. +     if (strcmp(type, "local") == 0) {
  1164. +         reader = read_clock_local;
  1165. +         cfd = init_clock_local(name);
  1166. +     }
  1167. + #ifdef PSTI
  1168. +     else if (strcmp(type, "psti") == 0) {
  1169. +         reader = read_clock_psti;
  1170. +         cfd = init_clock_psti(name);
  1171. +     }
  1172. + #endif PSTI
  1173. +     else {
  1174. +         if (debug) printf("Unknown reference type\n"); else
  1175. +         syslog(LOG_ERR, "Unknown reference clock type (%s)\n", type);
  1176. +         return(-1);
  1177. +     }
  1178. +     if (cfd >= 0) {
  1179. +         r = (struct refclock *)malloc(sizeof(struct refclock));
  1180. +         r->fd = cfd;
  1181. +         r->reader = reader;
  1182. +         r->next = refclocks;
  1183. +         refclocks = r;
  1184. +     }
  1185. +     return(cfd);
  1186. + }
  1187. + read_clock(cfd, tvpp, otvpp)
  1188. + int cfd;
  1189. + struct timeval **tvpp, **otvpp;
  1190. + {
  1191. +     struct refclock *r;
  1192. +     for (r = refclocks; r; r = r->next)
  1193. +         if(r->fd == cfd)
  1194. +             return((r->reader)(cfd, tvpp, otvpp));
  1195. +     return(1); /* Can't happen */
  1196. + }
  1197. + #endif
  1198.  
  1199. Index: ntpdc.c
  1200. *** ntpdc.c.old    Thu May 18 18:42:37 1989
  1201. --- ntpdc.c    Thu May 18 18:42:42 1989
  1202. ***************
  1203. *** 1,9 ****
  1204.   #ifndef    lint
  1205. ! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntpdc.c,v $ $Revision: 3.4.1.6 $ $Date: 89/05/03 15:17:27 $";
  1206.   #endif
  1207.   
  1208.   /*
  1209.    * $Log:    ntpdc.c,v $
  1210.    * Revision 3.4.1.6  89/05/03  15:17:27  louie
  1211.    * ntpdc now will display addional peer flags which indicate how far through
  1212.    * the clock selection process a peer was considered.
  1213. --- 1,12 ----
  1214.   #ifndef    lint
  1215. ! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntpdc.c,v $ $Revision: 3.4.1.7 $ $Date: 89/05/18 18:31:26 $";
  1216.   #endif
  1217.   
  1218.   /*
  1219.    * $Log:    ntpdc.c,v $
  1220. +  * Revision 3.4.1.7  89/05/18  18:31:26  louie
  1221. +  * A few cosmetic changes for ntpd.c
  1222. +  * 
  1223.    * Revision 3.4.1.6  89/05/03  15:17:27  louie
  1224.    * ntpdc now will display addional peer flags which indicate how far through
  1225.    * the clock selection process a peer was considered.
  1226. ***************
  1227. *** 70,75 ****
  1228. --- 73,79 ----
  1229.    * 
  1230.    */
  1231.   
  1232. + #include <sys/types.h>
  1233.   #include <sys/param.h>
  1234.   #include <signal.h>
  1235.   #include <sys/uio.h>
  1236. ***************
  1237. *** 262,268 ****
  1238.       }
  1239.       sp = getservbyname("ntp", "udp");
  1240.       if (sp == 0) {
  1241. !         fprintf(stderr,"udp/ntp: service unknown\nUsing default\n");
  1242.           watcher.sin_port = htons(NTP_PORT);
  1243.       } else
  1244.           watcher.sin_port = sp->s_port;
  1245. --- 266,273 ----
  1246.       }
  1247.       sp = getservbyname("ntp", "udp");
  1248.       if (sp == 0) {
  1249. !         fprintf(stderr,"udp/ntp: service unknown, using default %d\n",
  1250. !             NTP_PORT);
  1251.           watcher.sin_port = htons(NTP_PORT);
  1252.       } else
  1253.           watcher.sin_port = sp->s_port;
  1254. ***************
  1255. *** 324,330 ****
  1256.       struct clockinfo *n;
  1257.   {
  1258.       int i;
  1259. -     char ref_clock[5];
  1260.       struct in_addr clock_host;
  1261.       double offset[PEER_SHIFT], delay[PEER_SHIFT], dsp,del,off;
  1262.       char *cvthname();
  1263. --- 329,334 ----
  1264. ***************
  1265. *** 348,356 ****
  1266.              ntohs(n->flags),
  1267.              n->leap);
  1268.       if (n->stratum == 1 || n->stratum == 0) {
  1269. !         (void) strncpy(ref_clock, (char *) &n->refid, 4);
  1270. !         ref_clock[4] = '\0';
  1271. !         printf("Reference clock ID: %s", ref_clock);
  1272.       } else {
  1273.           clock_host.s_addr = (u_long) n->refid;
  1274.           printf("Reference clock ID: [%s]", inet_ntoa(clock_host));
  1275. --- 352,358 ----
  1276.              ntohs(n->flags),
  1277.              n->leap);
  1278.       if (n->stratum == 1 || n->stratum == 0) {
  1279. !         printf("Reference clock ID: %.4s", (char *)&n->refid);
  1280.       } else {
  1281.           clock_host.s_addr = (u_long) n->refid;
  1282.           printf("Reference clock ID: [%s]", inet_ntoa(clock_host));
  1283.  
  1284. Index: ntpsubs.c
  1285. *** ntpsubs.c.old    Thu May 18 18:42:53 1989
  1286. --- ntpsubs.c    Thu May 18 18:42:55 1989
  1287. ***************
  1288. *** 1,9 ****
  1289.   #ifndef    lint
  1290. ! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntpsubs.c,v $ $Revision: 3.4.1.2 $ $Date: 89/03/29 12:46:02 $";
  1291.   #endif    lint
  1292.   
  1293.   /*
  1294.    *  $Log:    ntpsubs.c,v $
  1295.    * Revision 3.4.1.2  89/03/29  12:46:02  louie
  1296.    * Check for success sending query before trying to listen for answers.  Will 
  1297.    * catch case of no server running and an ICMP port unreachable being returned.
  1298. --- 1,17 ----
  1299.   #ifndef    lint
  1300. ! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntpsubs.c,v $ $Revision: 3.4.1.3 $ $Date: 89/05/18 18:33:50 $";
  1301.   #endif    lint
  1302.   
  1303.   /*
  1304.    *  $Log:    ntpsubs.c,v $
  1305. +  * Revision 3.4.1.3  89/05/18  18:33:50  louie
  1306. +  * Added support few a new type of unsigned long to double compiler brokenness,
  1307. +  * called GENERIC_UNS_BUG.  If this is defined, then the unsigned long is
  1308. +  * shifted right one bit, the high-order bit of the result is cleared, then
  1309. +  * converted to a double.  The double is multiplied by 2.0, and the a 1.0 is
  1310. +  * optionall added to it if the low order bit of the original unsigned long
  1311. +  * was set.  Whew!
  1312. +  * 
  1313.    * Revision 3.4.1.2  89/03/29  12:46:02  louie
  1314.    * Check for success sending query before trying to listen for answers.  Will 
  1315.    * catch case of no server running and an ICMP port unreachable being returned.
  1316. ***************
  1317. *** 35,40 ****
  1318. --- 43,49 ----
  1319.    */
  1320.   
  1321.   #include <stdio.h>
  1322. + #include <sys/types.h>
  1323.   #include <sys/param.h>
  1324.   #include <sys/time.h>
  1325.   #include <sys/uio.h>
  1326. ***************
  1327. *** 59,65 ****
  1328. --- 68,88 ----
  1329.       struct l_fixedpt *t;
  1330.   {
  1331.       double a, b;
  1332. + #ifdef    GENERIC_UNS_BUG
  1333. +     register int i;
  1334.   
  1335. +     i = ntohl(t->fraction);
  1336. +     a = (long)((i >> 1) & 0x7fffffff);
  1337. +     a *= 2.0;
  1338. +     if (i & 1)
  1339. +         a += 1.0;
  1340. +     a = a / (4.294967296e9);    /* shift dec point over by 32 bits */
  1341. +     i = ntohl(t->int_part);
  1342. +     b = (long)((i >> 1) & 0x7fffffff);
  1343. +     b *= 2.0;
  1344. +     if (i & 1)
  1345. +         b += 1.0;
  1346. + #else    /* GENERIC_UNS_BUG */
  1347.       a = (unsigned long) ntohl(t->fraction);
  1348.   #ifdef    VAX_COMPILER_FLT_BUG
  1349.       if (a < 0.0) a += 4.294967296e9;
  1350. ***************
  1351. *** 69,81 ****
  1352.   #ifdef    VAX_COMPILER_FLT_BUG
  1353.       if (b < 0.0) b += 4.294967296e9;
  1354.   #endif
  1355. !     a += b;    /* add rest of integer part */
  1356. !     return (a);
  1357.   }
  1358.   
  1359.   /*
  1360.    *  Here we have to worry about the high order bit being signed
  1361.    */
  1362.   double
  1363.   l_fixed_to_double(t)
  1364.       struct l_fixedpt *t;
  1365. --- 92,106 ----
  1366.   #ifdef    VAX_COMPILER_FLT_BUG
  1367.       if (b < 0.0) b += 4.294967296e9;
  1368.   #endif
  1369. ! #endif    /* GENERIC_UNS_BUG */
  1370. !     return (a + b);
  1371.   }
  1372.   
  1373.   /*
  1374.    *  Here we have to worry about the high order bit being signed
  1375.    */
  1376. + #if    0
  1377.   double
  1378.   l_fixed_to_double(t)
  1379.       struct l_fixedpt *t;
  1380. ***************
  1381. *** 108,113 ****
  1382. --- 133,139 ----
  1383.       }
  1384.       return (a);
  1385.   }
  1386. + #endif
  1387.   
  1388.   /*
  1389.    *  Here we have to worry about the high order bit being signed
  1390.  
  1391. Index: read_local.c
  1392. *** read_local.c.old    Thu May 18 18:43:01 1989
  1393. --- read_local.c    Thu May 18 18:43:02 1989
  1394. ***************
  1395. *** 0 ****
  1396. --- 1,30 ----
  1397. + #ifdef    REFCLOCK
  1398. + /*
  1399. +  *  A dummy clock reading routine that reads the current system time.
  1400. +  *  from the local host.  Its possible that this could be actually used
  1401. +  *  if the system was in fact a very accurate time keeper (a true real-time
  1402. +  *  system with good crystal clock or better).
  1403. +  */
  1404. + #include <sys/types.h>
  1405. + #include <sys/time.h>
  1406. + init_clock_local(file)
  1407. + char *file;
  1408. + {
  1409. +     return getdtablesize();    /* invalid if we ever use it */
  1410. + }
  1411. + read_clock_local(cfd, tvp, mtvp)
  1412. + int cfd;
  1413. + struct timeval **tvp, **mtvp;
  1414. + {
  1415. +     static struct timeval realtime, mytime;
  1416. +     gettimeofday(&realtime, 0);
  1417. +     mytime = realtime;
  1418. +     *tvp = &realtime;
  1419. +     *mtvp = &mytime;
  1420. +     return(0);
  1421. + }
  1422. + #endif
  1423.  
  1424. Index: read_psti.c
  1425. *** read_psti.c.old    Thu May 18 18:43:07 1989
  1426. --- read_psti.c    Thu May 18 18:43:09 1989
  1427. ***************
  1428. *** 0 ****
  1429. --- 1,369 ----
  1430. + #if    defined(REFCLOCK) && defined(PSTI)
  1431. + #ifndef    lint
  1432. + static char *rcsid = "$Header: /usr/users/louie/ntp/RCS/read_psti.c,v 3.4.1.1 89/05/18 18:36:45 louie Exp Locker: louie $";
  1433. + static char *sccsid = "@(#)read_psti.c    1.1    MS/ACF    89/02/17";
  1434. + #endif    lint
  1435. + #define    ERR_RATE    60    /* Repeat errors once an hour */
  1436. + /*
  1437. +  * read_psti.c
  1438. +  *     January 1988 -- orignal by Jeffrey I. Schiller <JIS@BITSY.MIT.EDU>
  1439. +  *     January 1989 -- QU version by Doug Kingston <DPK@Morgan.COM>
  1440. +  *
  1441. +  *   This module facilitates reading a Precision Time Standard, Inc.
  1442. +  *   WWV radio clock. We assume that clock is configured for 9600 baud,
  1443. +  *   no parity. Output is accepted in either 24 or 12 hour format.
  1444. +  *   Time is requested and processed in GMT.
  1445. +  *
  1446. +  *   This version is designed to make use of the QU command due to
  1447. +  *   additional information it provides (like date and flags).
  1448. +  *   Select is used to prevent hanging in a read when there are
  1449. +  *   no characters to read.  The line is run in cooked mode to
  1450. +  *   reduce overhead.
  1451. +  *
  1452. +  *   This requires a PSTI ROM revision later 4.01.000 or later.
  1453. +  *
  1454. +  *   Routines defined:
  1455. +  *    init_clock_psti(): Open the tty associated with the clock and
  1456. +  *               set its tty mode bits. Returns fd on success
  1457. +  *               and -1 on failure.
  1458. +  *    read_clock_psti(): Reads the clock and returns either 0 on success
  1459. +  *               or non-zero on error.  On success, pointers are
  1460. +  *               provided to the reference and local time.
  1461. +  */
  1462. + #include <stdio.h>
  1463. + #include <syslog.h>
  1464. + #include <sys/time.h>
  1465. + #include <sys/types.h>
  1466. + #include <sys/ioctl.h>
  1467. + #if defined(sun)
  1468. + #include <termio.h>
  1469. + #endif
  1470. + #ifdef    DEBUG
  1471. + extern int debug;
  1472. + #endif    DEBUG
  1473. + static int nerrors = 0;
  1474. + static char clockdata[32];
  1475. + #define    MIN_READ 13        /* for Rev 4.01.001 */
  1476. + static double reltime();
  1477. + #ifdef STANDALONE
  1478. + #ifndef CLOCKDEV
  1479. + #define CLOCKDEV "/dev/radioclock"
  1480. + #endif
  1481. + #define DEBUG    1
  1482. + int debug = 1;
  1483. + main(argc, argv)
  1484. + int argc;
  1485. + char **argv;
  1486. + {
  1487. +     struct timeval *tvp, *otvp;
  1488. +     debug = argc;
  1489. +     if (openclock(CLOCKDEV))
  1490. +         do {
  1491. +             (void)readclock(&tvp, &otvp);
  1492. +             sleep(1);
  1493. +         } while (debug>1);
  1494. +     exit(0);
  1495. + }
  1496. + #endif STANDALONE
  1497. + init_clock_psti(timesource)
  1498. + char *timesource;
  1499. + {
  1500. +     int cfd;
  1501. + #ifdef TCSETA
  1502. +     struct termio tty;
  1503. + #else
  1504. +     struct sgttyb tty;
  1505. + #endif
  1506. +     if ((cfd = open(timesource, 2)) < 0) {
  1507. + #ifdef DEBUG
  1508. +         if (debug) perror(timesource); else
  1509. + #endif DEBUG
  1510. +         syslog(LOG_ERR, "can't open %s: %m", timesource);
  1511. +         return(-1);
  1512. +     }
  1513. +     if (ioctl(cfd, TIOCEXCL, 0) < 0) {
  1514. + #ifdef DEBUG
  1515. +         if (debug) perror("TIOCEXCL on radioclock failed"); else
  1516. + #endif DEBUG
  1517. +         syslog(LOG_ERR, "TIOCEXCL on %s failed: %m", timesource);
  1518. +         return(-1);
  1519. +     }
  1520. + #ifdef TCSETA
  1521. +     if (ioctl(cfd, TCGETA, &tty) < 0) {
  1522. + #ifdef DEBUG
  1523. +         if (debug) perror("ioctl on radioclock failed"); else
  1524. + #endif DEBUG
  1525. +         syslog(LOG_ERR, "ioctl on %s failed: %m", timesource);
  1526. +         return(-1);
  1527. +     }
  1528. +     tty.c_cflag = (B9600<<16)|B9600|CS8|CLOCAL|CREAD;
  1529. +     tty.c_iflag = ICRNL;
  1530. +     tty.c_oflag = 0;
  1531. +     tty.c_lflag = 0;
  1532. +     bzero((char *)tty.c_cc, sizeof tty.c_cc);
  1533. +     tty.c_cc[VMIN] = MIN_READ;
  1534. +     tty.c_cc[VTIME] = 0;
  1535. +     if (ioctl(cfd, TCSETA, &tty) < 0) {
  1536. + #else TCSETA    /* Use older Berkeley style IOCTL's */
  1537. +     bzero((char *)&tty, sizeof tty);
  1538. +     tty.sg_ispeed = tty.sg_ospeed = B9600;
  1539. +     tty.sg_flags = ANYP|CRMOD;
  1540. +     tty.sg_erase = tty.sg_kill = '\0';
  1541. +     if (ioctl(cfd, TIOCSETP, &tty) < 0) {
  1542. + #endif TCSETA
  1543. + #ifdef DEBUG
  1544. +         if (debug) perror("ioctl on radioclock failed"); else
  1545. + #endif DEBUG
  1546. +         syslog(LOG_ERR, "ioctl on %s failed: %m", timesource);
  1547. +         return(-1);
  1548. +     }
  1549. +     if (write(cfd, "xxxxxxsn\r", 9) != 9) {
  1550. + #ifdef DEBUG
  1551. +         if (debug) perror("init write to radioclock failed"); else
  1552. + #endif DEBUG
  1553. +         syslog(LOG_ERR, "init write to %s failed: %m", timesource);
  1554. +         return(-1);
  1555. +     }
  1556. +     return(cfd);            /* Succeeded in opening the clock */
  1557. + }
  1558. + /*
  1559. +  * read_clock_psti() -- Read the PSTI Radio Clock.
  1560. +  */
  1561. + read_clock_psti(cfd, tvpp, otvpp)
  1562. + int cfd;
  1563. + struct timeval **tvpp, **otvpp;
  1564. + {
  1565. +     static struct timeval radiotime;
  1566. +     static struct timeval mytime;
  1567. +     struct timeval timeout;
  1568. +     struct tm *mtm;
  1569. +     struct tm radio_tm, *rtm = &radio_tm;
  1570. +     register int i;
  1571. +     register int millis;
  1572. +     register double diff;
  1573. +     int stat1, stat2;
  1574. +     fd_set readfds;
  1575. +     char message[256];
  1576. + #ifndef TCSETA
  1577. +     register char *cp;
  1578. +     int  need;
  1579. + #endif TCSETA
  1580. +     FD_ZERO(&readfds);
  1581. +     FD_SET(cfd, &readfds);
  1582. +     timeout.tv_sec = 2;
  1583. +     timeout.tv_usec = 0;
  1584. +     (void) ioctl(cfd, TIOCFLUSH, 0);    /* scrap the I/O queues */
  1585. +     /* BEGIN TIME CRITICAL CODE SECTION!!!!!! */
  1586. +     /* EVERY CYCLE FROM THIS POINT OUT ADDS TO THE INACCURACY OF
  1587. +          THE READ CLOCK VALUE!!!!! */
  1588. +     if (write(cfd, "\003qu0000", 7) != 7) {
  1589. + #ifdef DEBUG
  1590. +         if (debug) printf("radioclock write failed\n"); else
  1591. + #endif DEBUG
  1592. +         if ((nerrors++%ERR_RATE) == 0)
  1593. +             syslog(LOG_ERR, "write to radioclock failed: %m");
  1594. +         return(1);
  1595. +     }
  1596. +     if(select(cfd+1, &readfds, 0, 0, &timeout) != 1) {
  1597. + #ifdef DEBUG
  1598. +         if (debug) printf("radioclock poll timed out\n"); else
  1599. + #endif DEBUG
  1600. +         if ((nerrors++%ERR_RATE) == 0)
  1601. +             syslog(LOG_ERR, "poll of radioclock failed: %m");
  1602. +         return(1);
  1603. +     }
  1604. +     if ((i = read(cfd, clockdata, sizeof clockdata)) < MIN_READ) {
  1605. + #ifdef DEBUG
  1606. +         if (debug) printf("radioclock read error (%d)\n", i); else
  1607. + #endif DEBUG
  1608. +         if ((nerrors++%ERR_RATE) == 0)
  1609. +             syslog(LOG_ERR, "radioclock read error (%d!=13): %m", i);
  1610. +         return(1);
  1611. +     }
  1612. +     (void) gettimeofday(&mytime, (struct timezone *)0);
  1613. +     /* END OF TIME CRITICAL CODE SECTION!!!! */
  1614. +     if (clockdata[i-1] != '\n') {
  1615. + #ifdef DEBUG
  1616. +         if (debug) printf("radioclock format error1 (%.12s)(0x%x)\n",
  1617. +             clockdata, clockdata[12]); else
  1618. + #endif DEBUG
  1619. +         if ((nerrors++%ERR_RATE) == 0)
  1620. +             syslog(LOG_ERR, "radioclock format error1 (%.12s)(0x%x)",
  1621. +                 clockdata, clockdata[12]);
  1622. +         return(1);
  1623. +     }
  1624. +     for (i = 0; i < 12; i++) {
  1625. +         if (clockdata[i] < '0' || clockdata[i] > 'o') {
  1626. + #ifdef DEBUG
  1627. +             if (debug) printf("radioclock format error2\n"); else
  1628. + #endif DEBUG
  1629. +             if ((nerrors++%ERR_RATE) == 0)
  1630. +                 syslog(LOG_ERR, "radioclock format error2\n");
  1631. +             return(1);
  1632. +         }
  1633. +     }
  1634. +     stat1 = clockdata[0]-'0';
  1635. +     stat2 = clockdata[1]-'0';
  1636. +     millis = ((clockdata[2]-'0')*64)+(clockdata[3]-'0');
  1637. +     rtm->tm_sec = (clockdata[4]-'0');
  1638. +     rtm->tm_min = (clockdata[5]-'0');
  1639. +     rtm->tm_hour = (clockdata[6]-'0');
  1640. +     rtm->tm_yday = ((clockdata[7]-'0')*64)+(clockdata[8]-'0')-1;
  1641. +     rtm->tm_year = 86+(clockdata[9]-'0');
  1642. +     /* byte 10 and 11 reserved */
  1643. +     /*
  1644. +      * Correct "hours" based on whether or not AM/PM mode is enabled.
  1645. +      * If clock is in 24 hour (military) mode then no correction is
  1646. +      * needed.
  1647. +      */
  1648. +     if(stat2&0x10) {        /* Map AM/PM time to Military */
  1649. +         if (stat2&0x8) {
  1650. +             if (rtm->tm_hour != 12) rtm->tm_hour += 12;
  1651. +         } else {
  1652. +             if (rtm->tm_hour == 12) rtm->tm_hour = 0;
  1653. +         }
  1654. +     }
  1655. +     if (stat1 != 0x4 && (nerrors++%ERR_RATE)==0) {
  1656. + #ifdef DEBUG
  1657. +         if (debug) printf("radioclock fault #%d 0x%x:%s%s%s%s%s%s\n",
  1658. +             nerrors, stat1,
  1659. +             stat1&0x20?" Out of Spec,":"",
  1660. +             stat1&0x10?" Hardware Fault,":"",
  1661. +             stat1&0x8?" Signal Fault,":"",
  1662. +             stat1&0x4?" Time Avail,":"",
  1663. +             stat1&0x2?" Year Mismatch,":"",
  1664. +             stat1&0x1?" Clock Reset,":"");
  1665. +         else {
  1666. + #endif DEBUG
  1667. +             sprintf(message, "radioclock fault #%d 0x%x:%s%s%s%s%s%s\n",
  1668. +                 nerrors, stat1,
  1669. +                 stat1&0x20?" Out of Spec,":"",
  1670. +                 stat1&0x10?" Hardware Fault,":"",
  1671. +                 stat1&0x8?" Signal Fault,":"",
  1672. +                 stat1&0x4?" Time Avail,":"",
  1673. +                 stat1&0x2?" Year Mismatch,":"",
  1674. +                 stat1&0x1?" Clock Reset,":"");
  1675. +             syslog(LOG_ERR, message);
  1676. +         }
  1677. +     }
  1678. +     if (stat1&0x38) /* Out of Spec, Hardware Fault, Signal Fault */
  1679. +         return(1);
  1680. +     if ((millis > 999 || rtm->tm_sec > 60 || rtm->tm_min > 60 ||
  1681. +          rtm->tm_hour > 23 || rtm->tm_yday > 365) && (nerrors++%ERR_RATE)==0) {
  1682. + #ifdef DEBUG
  1683. +         if (debug) printf("radioclock bogon #%d: %dd %dh %dm %ds %dms\n",
  1684. +             nerrors, rtm->tm_yday, rtm->tm_hour,
  1685. +             rtm->tm_min, rtm->tm_sec, millis);
  1686. +         else
  1687. + #endif DEBUG
  1688. +         sprintf(message, "radioclock bogon #%d: %dd %dh %dm %ds %dms\n",
  1689. +             nerrors, rtm->tm_yday, rtm->tm_hour,
  1690. +             rtm->tm_min, rtm->tm_sec, millis);
  1691. +         syslog(LOG_ERR, message);
  1692. +         return(1);
  1693. +     }
  1694. +     mtm = gmtime(&mytime.tv_sec);
  1695. +     diff =  reltime(rtm, millis*1000) - reltime(mtm, mytime.tv_usec);
  1696. + #ifdef DEBUG
  1697. +     if (debug > 1)
  1698. +         printf("Clock time:  19%d day %03d %02d:%02d:%02d.%03d diff %.3f\n",
  1699. +             rtm->tm_year, rtm->tm_yday, rtm->tm_hour,
  1700. +             rtm->tm_min, rtm->tm_sec, millis, diff);
  1701. + #endif DEBUG
  1702. +     
  1703. +     if (diff > (90*24*60*60.0) && (nerrors++%ERR_RATE)==0) {
  1704. + #ifdef DEBUG
  1705. +         if (debug)
  1706. +             printf("offset excessive (system 19%d/%d, clock 19%d/%d)\n",
  1707. +                 mtm->tm_year, mtm->tm_yday,
  1708. +                 rtm->tm_year, mtm->tm_yday);
  1709. +         else
  1710. + #endif DEBUG
  1711. +         syslog(LOG_ERR, "offset excessive (system 19%d/%d, clock 19%d/%d)\n",
  1712. +                 mtm->tm_year, mtm->tm_yday,
  1713. +                 rtm->tm_year, mtm->tm_yday);
  1714. +         return(1);
  1715. +     }
  1716. +     diff += (double)mytime.tv_sec + ((double)mytime.tv_usec/1000000.0);
  1717. +     radiotime.tv_sec = diff;
  1718. +     radiotime.tv_usec = (diff - (double)radiotime.tv_sec) * 1000000;
  1719. + #ifdef DEBUG
  1720. +     if (debug > 1) {
  1721. +         printf("System time: 19%d day %03d %02d:%02d:%02d.%03d\n",
  1722. +             mtm->tm_year, mtm->tm_yday, mtm->tm_hour,
  1723. +             mtm->tm_min, mtm->tm_sec, mytime.tv_usec/1000);
  1724. +         printf("stat1 0%o, stat2 0%o: ", stat1, stat2);
  1725. +         if (stat1 || stat2)
  1726. +             printf("%s%s%s%s%s%s%s%s%s%s%s%s",
  1727. +                 stat1&0x20?" Out of Spec,":"",
  1728. +                 stat1&0x10?" Hardware Fault,":"",
  1729. +                 stat1&0x8?" Signal Fault,":"",
  1730. +                 stat1&0x4?" Time Avail,":"",
  1731. +                 stat1&0x2?" Year Mismatch,":"",
  1732. +                 stat1&0x1?" Clock Reset,":"",
  1733. +                 stat2&0x20?" DST on,":"",
  1734. +                 stat2&0x10?" 12hr mode,":"",
  1735. +                 stat2&0x8?" PM,":"",
  1736. +                 stat2&0x4?" Spare?,":"",
  1737. +                 stat2&0x2?" DST??? +1,":"",
  1738. +                 stat2&0x1?" DST??? -1,":"");
  1739. +         printf("\n");
  1740. +     }
  1741. + #endif DEBUG
  1742. +     /* If necessary, acknowledge "Clock Reset" flag bit */
  1743. +     if (stat1 & 0x1) {
  1744. +         if (write(cfd, "si0", 3) != 3) {
  1745. + #ifdef DEBUG
  1746. +             if (debug) printf("radioclock reset write failed\n"); else
  1747. + #endif DEBUG
  1748. +             syslog(LOG_ERR, "reset write to radioclock failed: %m");
  1749. +             return(1);
  1750. +         }
  1751. +     }
  1752. +     if (nerrors && stat1==0x4) {
  1753. +         syslog(LOG_ERR, "radioclock OK (after %d errors)", nerrors);
  1754. +         nerrors = 0;
  1755. +     }
  1756. +     *tvpp = &radiotime;
  1757. +     *otvpp = &mytime;
  1758. +     return(0);
  1759. + }
  1760. + static double
  1761. + reltime(tm, usec)
  1762. + register struct tm *tm;
  1763. + register int usec;
  1764. + {
  1765. +     return(tm->tm_year*(366.0*24.0*60.0*60.0) +
  1766. +            tm->tm_yday*(24.0*60.0*60.0) +
  1767. +            tm->tm_hour*(60.0*60.0) +
  1768. +            tm->tm_min*(60.0) +
  1769. +            tm->tm_sec +
  1770. +            usec/1000000.0);
  1771. + }
  1772. + #endif
  1773.  
  1774. Index: test.c
  1775. *** test.c.old    Thu May 18 18:43:20 1989
  1776. --- test.c    Thu May 18 18:43:22 1989
  1777. ***************
  1778. *** 1,9 ****
  1779.   #ifndef    lint
  1780. ! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/test.c,v $ $Revision: 3.4.1.3 $ $Date: 89/04/07 19:10:41 $";
  1781.   #endif
  1782.   
  1783.   /*
  1784.    * $Log:    test.c,v $
  1785.    * Revision 3.4.1.3  89/04/07  19:10:41  louie
  1786.    * Add check for SUN_FLT_BUG problem in test.c
  1787.    * 
  1788. --- 1,12 ----
  1789.   #ifndef    lint
  1790. ! static char *RCSid = "$Source: /usr/users/louie/ntp/RCS/test.c,v $ $Revision: 3.4.1.4 $ $Date: 89/05/18 18:37:39 $";
  1791.   #endif
  1792.   
  1793.   /*
  1794.    * $Log:    test.c,v $
  1795. +  * Revision 3.4.1.4  89/05/18  18:37:39  louie
  1796. +  * Add test for GENERIC_UNS_BUG to test.c
  1797. +  * 
  1798.    * Revision 3.4.1.3  89/04/07  19:10:41  louie
  1799.    * Add check for SUN_FLT_BUG problem in test.c
  1800.    * 
  1801. ***************
  1802. *** 95,101 ****
  1803. --- 98,106 ----
  1804.           printf(" %4.2f ", value[i]);
  1805.           double_to_l_fixed(&sample, value[i]);
  1806.           printf(" x%#8X.%#8X ", sample.int_part, sample.fraction);
  1807. + #if    0
  1808.           printf(" %4.2f", l_fixed_to_double(&sample));
  1809. + #endif
  1810.           printf("\t");
  1811.           double_to_s_fixed(&s_sample, value[i]);
  1812.           printf(" x%#4X.%#4X ", s_sample.int_part, s_sample.fraction);
  1813. ***************
  1814. *** 126,139 ****
  1815.       unsigned long ul = 0x80000001;
  1816.       double dbl;
  1817.   
  1818.       dbl = ul;
  1819.   #ifdef    VAX_COMPILER_FLT_BUG
  1820.       if (dbl < 0.0) dbl += 4.294967296e9;
  1821.   #endif
  1822.       if (dbl != 2147483649.0) {
  1823.           printf("test3 fails: can't convert from unsigned long to float\n");
  1824.           printf("             (%lu != %15g)\n", ul, dbl);
  1825. !         printf("Try defining VAX_COMPILER_FLT_BUG in the Makefile.\n");
  1826.           return 1;
  1827.       } else {
  1828.           if (v)
  1829. --- 131,156 ----
  1830.       unsigned long ul = 0x80000001;
  1831.       double dbl;
  1832.   
  1833. + #ifdef    GENERIC_UNS_BUG
  1834. +     /*
  1835. +      *  Hopefully, we can avoid the unsigned issue altogether.  Make sure
  1836. +      *  that the high-order (sign) bit is zero, and fiddle from there 
  1837. +      */
  1838. +     dbl = (long)((ul >> 1) & 0x7fffffff);
  1839. +     dbl *= 2.0;
  1840. +     if (ul & 1)
  1841. +         dbl += 1.0;
  1842. + #else
  1843.       dbl = ul;
  1844.   #ifdef    VAX_COMPILER_FLT_BUG
  1845.       if (dbl < 0.0) dbl += 4.294967296e9;
  1846.   #endif
  1847. + #endif
  1848.       if (dbl != 2147483649.0) {
  1849.           printf("test3 fails: can't convert from unsigned long to float\n");
  1850.           printf("             (%lu != %15g)\n", ul, dbl);
  1851. !         printf(
  1852. !   "Try defining VAX_COMPILER_FLT_BUG or GENERIC_UNS_BUG in the Makefile.\n");
  1853.           return 1;
  1854.       } else {
  1855.           if (v)
  1856.